﻿namespace MefContrib.Models.Provider.Definitions.Fluent
{
    using System;
    using System.Linq;

    public class ImportDecorator : Decorator
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ImportDecorator"/> class, using
        /// the specified <see cref="Provider"/> instance.
        /// </summary>
        /// <param name="provider">The <see cref="FluentDefinitionProvider"/> which is being decorated for an import.</param>
        public ImportDecorator(FluentDefinitionProvider provider)
            : base(provider)
        {
        }

        /// <summary>
        /// Adds a required metadata element name to the currect <see cref="ImportDescription"/>.
        /// </summary>
        /// <param name="name">The name of the metadata element.</param>
        /// <returns>An <see cref="ImportDecorator"/> object.</returns>
        public virtual ImportDecorator AddRequiredMetadata(string name)
        {
            CurrentPart.Imports.Last().RequiredMetadata.Add(name);
            return this;
        }

        /// <summary>
        /// Gets a value indicating whether the property or field will be set to its type's default value when 
        /// an export with the contract name is not present in the container.
        /// </summary>
        /// <param name="allowDefault"><see langword="true"/> if default values are permitted; otherwise <see langword="false"/>.</param>
        /// <returns>An <see cref="ImportDecorator"/> object.</returns>
        /// <remarks>The default value is <see langword="true"/>.</remarks>
        public virtual ImportDecorator AllowDefault(bool allowDefault)
        {
            CurrentPart.Imports.Last().AllowDefault = allowDefault;
            return this;
        }

        /// <summary>
        /// Gets a value indicating whether the import definition is required to be satisfied before a part
        /// can start producing exported objects.
        /// </summary>
        /// <param name="isPrerequisite"><see langword="true"/> if the import is a prerequisite; otherwise <see langword="false"/>.</param>
        /// <returns>An <see cref="ImportDecorator"/> object.</returns>
        /// <remarks>The default value is <see langword="false"/>.</remarks>
        public virtual ImportDecorator IsPrerequisite(bool isPrerequisite)
        {
            CurrentPart.Imports.Last().Prerequisite = isPrerequisite;
            return this;
        }

        /// <summary>
        /// Gets a value indicating whether the import definition can be satisfied multiple times.
        /// </summary>
        /// <param name="isRecomposable"><see langword="true"/> if the import is recomposable; otherwise <see langword="false"/>.</param>
        /// <returns>An <see cref="ImportDecorator"/> object.</returns>
        /// <remarks>The default value is <see langword="false"/>.</remarks>
        public virtual ImportDecorator IsRecomposable(bool isRecomposable)
        {
            CurrentPart.Imports.Last().Recomposable = isRecomposable;
            return this;
        }

        /// <summary>
        /// Assigns a contract to the current <see cref="ImportDescription"/>.
        /// </summary>
        /// <param name="contract">A <see cref="String"/> containing the contract.</param>
        /// <returns>An <see cref="ImportDecorator"/> object.</returns>
        public virtual ImportDecorator WithContract(string contract)
        {
            CurrentPart.Imports.Last().ContractName = contract;
            return this;
        }

        /// <summary>
        /// Assigns a contract to the current <see cref="ImportDescription"/>.
        /// </summary>
        /// <returns>An <see cref="ImportDecorator"/> object.</returns>
        public virtual ImportDecorator WithContract<TContract>()
        {
            CurrentPart.Imports.Last().ContractType = typeof(TContract);
            return this;
        }
    }
}